/*
 * Copyright 2008 Jiri Janak
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.floorballcoaches.exercisedrawer;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Point;
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
import java.awt.image.BufferedImage;

/**
 *
 * @author Jiri Janak
 */
public class GraphicsTools {

    public static BufferedImage colorOverlay(Image image, Color color) {

        int width = image.getWidth(null);
        int height = image.getHeight(null);

        BufferedImage sourceImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
        Graphics2D gfx = sourceImage.createGraphics();
        gfx.drawImage(image, 0, 0, null);
        gfx.dispose();

        int rgbDifference = color.getRGB() - Color.BLACK.getRGB();

        BufferedImage resultImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
        for (int x = 0; x < width; x++) {
            for (int y = 0; y < height; y++) {
                int actualPixelColor = sourceImage.getRGB(x, y);
                resultImage.setRGB(x, y, actualPixelColor | rgbDifference);
            }
        }

        return resultImage;
    }

    //cuts image from right top
    public static BufferedImage cut(Image image, int maxWidth, int maxHeight) {
        BufferedImage imageCut = new BufferedImage(maxWidth, maxHeight, BufferedImage.TYPE_INT_ARGB);
        Graphics2D graphicsCut = imageCut.createGraphics();
        /* public abstract boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, Color bgcolor, ImageObserver observer)
        img - the specified image to be drawn. This method does nothing if img is null.
        dx1 - the x coordinate of the first corner of the destination rectangle.
        dy1 - the y coordinate of the first corner of the destination rectangle.
        dx2 - the x coordinate of the second corner of the destination rectangle.
        dy2 - the y coordinate of the second corner of the destination rectangle.
        sx1 - the x coordinate of the first corner of the source rectangle.
        sy1 - the y coordinate of the first corner of the source rectangle.
        sx2 - the x coordinate of the second corner of the source rectangle.
        sy2 - the y coordinate of the second corner of the source rectangle.
        observer - object to be notified as more of the image is scaled and converted.
         */
        graphicsCut.drawImage(image,
                0, 0,
                maxWidth, maxHeight,
                image.getWidth(null) - maxWidth, 0,
                image.getWidth(null), image.getHeight(null),
                null);
        graphicsCut.dispose();
        return imageCut;
    }

    public static BufferedImage rotate(Image image, double rotationAngle) {
        AffineTransform trans = new AffineTransform();
        trans.setToRotation(Math.toRadians(rotationAngle));
        //trans.rotate( Math.toRadians(rotationAngle) );

        Point2D leftTop = new Point(0,0);
        Point2D newLeftTop = null;
        Point2D rightTop = new Point(image.getWidth(null),0);
        Point2D newRightTop = null;
        Point2D leftBottom = new Point(0,image.getHeight(null));
        Point2D newLeftBottom = null;
        Point2D rightBottom = new Point(image.getWidth(null),image.getHeight(null));
        Point2D newRightBottom = null;

        newLeftTop = trans.transform(leftTop, newLeftTop);
        newRightTop = trans.transform(rightTop, newRightTop);
        newLeftBottom = trans.transform(leftBottom, newLeftBottom);
        newRightBottom = trans.transform(rightBottom, newRightBottom);

        System.out.println(leftTop + "|" + newLeftTop);
        System.out.println(rightTop + "|" + newRightTop);
        System.out.println(leftBottom + "|" + newLeftBottom);
        System.out.println(rightBottom + "|" + newRightBottom);

        double[] x = {newLeftTop.getX(), newRightTop.getX(), newLeftBottom.getX(), newRightBottom.getX()};
        double[] y = {newLeftTop.getY(), newRightTop.getY(), newLeftBottom.getY(), newRightBottom.getY()};

        double minX = Double.POSITIVE_INFINITY;
        double maxX = Double.NEGATIVE_INFINITY;
        for (double d : x) {
            if (d < minX) minX = d;
            if (d > maxX) maxX = d;
        }
        double distX = maxX - minX;

        double minY = Double.POSITIVE_INFINITY;
        double maxY = Double.NEGATIVE_INFINITY;
        for (double d : y) {
            if (d < minY) minY = d;
            if (d > maxY) maxY = d;
        }
        double distY = maxY - minY;

        int width = image.getWidth(null);
        int height = image.getHeight(null);

        width = (int) distX;
        height = (int) distY;

        //BufferedImage imageRotate = new BufferedImage(image.getWidth(null), image.getHeight(null), BufferedImage.TYPE_INT_ARGB);
        BufferedImage imageRotate = new BufferedImage(width*2, height*2, BufferedImage.TYPE_INT_ARGB);
        Graphics2D graphicsCut = imageRotate.createGraphics();
        //graphicsCut.drawImage(image, trans, null);

        int newX = width;
        int newY = -height;

        graphicsCut.transform(trans);
        graphicsCut.drawImage(image, newX, newY, null);

        return imageRotate;
    }

    public static double angleBetweenPoints(int x1, int y1, int x2, int y2) {
        Point one = new Point(x1, y1);
        Point two = new Point(x2, y2);
        return GraphicsTools.angleBetweenPoints(one, two);
    }

    public static double angleBetweenPoints(Point a, Point b) {
        double dx = b.getX() - a.getX();
        double dy = b.getY() - a.getY();
        double angle = 0.0d;

        if (dx == 0.0) {
            if (dy == 0.0) {
                angle = 0.0;
            } else if (dy > 0.0) {
                angle = Math.PI / 2.0;
            } else {
                angle = (Math.PI * 3.0) / 2.0;
            }
        } else if (dy == 0.0) {
            if (dx > 0.0) {
                angle = 0.0;
            } else {
                angle = Math.PI;
            }
        } else {
            if (dx < 0.0) {
                angle = Math.atan(dy / dx) + Math.PI;
            } else if (dy < 0.0) {
                angle = Math.atan(dy / dx) + (2 * Math.PI);
            } else {
                angle = Math.atan(dy / dx);
            }
        }
        return (angle * 180) / Math.PI;
    }
}
